# -*- coding: utf-8 -*-
def create_setting(line):
    category = ""
    field_id = ""
    default = ""
    count = 20
    try:
        while line[count] != ".":
            category += line[count]
            count += 1
        count += 1
        while line[count] != "=" and line[count] != " ":
            field_id += line[count]
            count += 1
            
        while line[count] == " " or line[count] == "=":
            count += 1
            
        default = line[count:]
        if default[-1] == "\n":
            default = default[0:-1]
        if default[0] == "\"" and default[-1] == "\"":
            default = default[1:-1]
    except:
        return
        
    if default == "":
        default = " "
        
    if default[0] == "{":
        return
        
    id = category + "." + field_id
    id = str(id)
    try:
        uiset = settings_ui[id]
        readable = uiset[0]
        title = uiset[1]
        in_type = uiset[2]
        options = []
        if in_type == "select":
            options = uiset[3]
    except:
        readable = category
        title = field_id
        if default == "True":
            in_type = "select"
            default = "on"
            options = ["on", "off"]
        elif default == "False":
            in_type = "select"
            default = "off"
            options = ["on", "off"]
        else:
            in_type = "text"
            options = ""
        
    settings.append([category, field_id, default, readable, title, in_type, options])
    
def build_data():
    """Reads 000_config then edits the settings and module variables"""
    try:
        session.eden_name
    except NameError:
        session.eden_name = 'sahanaeden'
    if session.eden_name == None:
        session.eden_name = 'sahanaeden'
    import os
    import string
    file = open(os.path.join('applications', session.eden_name, 'models', '000_config.py'), 'r')
    at_modules = False
    current_mod = ""
    for line in file:
        config_file.append(line)
        if line[:20] == "deployment_settings.":
            create_setting(line)
        if line == "deployment_settings.modules = Storage(\n":
            at_modules = True
            continue
        try:
            if at_modules and line[4] != " ":
                if line[4] == ")":
                    continue
                if line[4] != "#":
                    try:
                        i = str.find(line, " = Storage(")
                        if i != -1:
                            mod_name = line[4:i]
                            current_mod = mod_name
                            modules[mod_name] = ["on", ""]
                    except:
                        pass
                else:
                    try:
                        i = str.find(line, " = Storage(")
                        if i != -1:
                            mod_name = line[5:i]
                            current_mod = mod_name
                            modules[mod_name] = ["off", ""]
                    except:
                        pass
        except IndexError:
            pass
        if at_modules:
            flag = str.find(line, "name_nice = T(")
            if flag != -1:
                modules[current_mod][1] = line[flag+15:-4]
            
    file.close()

def index():
    build_data()
    """The main function, builds the setup form then displays it."""
    #Graphical representation of how inputs / page elements are add / stored
    #Form (Entire collection)
    #|
    #Fieldset (Groups of settings)
    #|
    #Table (Optional) (Not everything uses a table this is just for organization)
    #|
    #Input/Element (Individual setting)
    old_category = None
    form = FORM(_id='theForm', _name='form', _method='post', _enctype='multipart/form-data')
    
    #Checks for existing libraries
    table = TABLE()
    fieldset = FIELDSET(_id="test", _class="step table_spacing")
    fieldset.append(LEGEND("Library Requirements"))
    fieldset.append(table)
    form.append(fieldset)
    
    #creates the library page
    for l in libraries:
        try:
            #actual check occures here
            exec("import " + l)
            passed = IMG(_src='../static/img/check.png')
        except:
            passed = IMG(_src='../static/img/x.png')
        name = A(libraries[l]['name'], _href=libraries[l]['link'])
        description = LABEL(libraries[l]['description'])
        table.append(TR(TD(passed),TD(name),TD(description)))
        
    fieldset = FIELDSET()
    #Iterates through settings
    for s in settings:
        #Breaks the settings into their respective catagories / fieldsets
        if old_category == None or s[0] != old_category:
            fieldset = FIELDSET(_id=s[3], _class="step")
            table = TABLE()
            form.append(fieldset)
            fieldset.append(table)
            fieldset.append(LEGEND(s[3]))
            old_category = s[0]
        try:
          table.append(TR(TD(LABEL(s[4] , _for=s[1], _title=ui_helper[s[1]][1], _name=s[1])), TD(get_input_type(s))))
        except:
          table.append(TR(TD(LABEL(s[4] , _for=s[1], _name=s[1])), TD(get_input_type(s), _title=s[1])))
        
        
    fieldset = FIELDSET(_id='modules', _class="step")
    form.append(fieldset)
    fieldset.append(LEGEND("Enable/Disable Modules"))
    table = TABLE()
    fieldset.append(table)
   
    #Creates the module fieldset
    k = modules.keys()
    k.sort()
    for m in k:
        sel = SELECT(_id=m, _name=m, _title=m)
        if modules[m][0] == "on":
            sel.append(OPTION('on', _selected='selected'))
            sel.append(OPTION('off'))
        else:
            sel.append(OPTION('on'))
            sel.append(OPTION('off', _selected='selected'))
        if modules[m][1] == "":
            table.append(TR(TD(LABEL(m)),TD(sel)))
        else:
            table.append(TR(TD(LABEL(modules[m][1])),TD(sel)))

    #Adds buttons
    form.append(INPUT(_type='reset'))
    form.append(INPUT(_type='submit'))
    form.append(BR())
    form.append(INPUT(_type='button', _value='Save and Quit', _id='save_and_quit'))
    
    #Thrown when the form is submitted
    if form.accepts(request.vars, session):
        write_out()

    return dict(form=form) #return all the stuff
    
def get_input_type(s):
    """Returns the appropriate input type based on the value specified"""
    #If a selector is requested, build the selector and add its components.
    if s[5] == 'select':
        sel = SELECT()
        try:
            sel = SELECT(_id=s[1], _name=s[1], _title=ui_helper[s[1]][1], _class=ui_helper[s[1]][0])
        except:
            sel = SELECT(_id=s[1], _name=s[1], _title=s[1], _class=s[1])
          
        for v in s[6]:
            if v == s[2]:
                sel.append(OPTION(v, _selected='selected'))
            else:
                sel.append(OPTION(v))
        return sel
    else:
        #This one is fairly outdated and not currently used, but left in the code for
        #   future compatability
        input = INPUT()
        if s[5] == 'checkbox':
            
            try:
                fieldset.append(INPUT(_type=s[5], _value=s[2], value=s[2], _id=s[1], _name=s[1], _title=ui_helper[s[1]][1], _class=ui_helper[s[1]][0]))
            except:
                fieldset.append(INPUT(_type=s[5], _value=s[2], value=s[2], _id=s[1], _name=s[1], _title=s[1], _class=s[1]))
                
            return input
        else:
            try:
                input = INPUT(_type=s[5], _value=s[2], _id=s[1], _name=s[1], _title=ui_helper[s[1]][1], _class=ui_helper[s[1]][0])
            except:
                input = INPUT(_type=s[5], _value=s[2], _id=s[1], _name=s[1], _title=s[1], _class=s[1])
            
            try:
                input.requires = validation_settings[s[1]]
            except:
                pass
            
            return input
 
def edit_setting(s):
    import string
    for c in range(len(config_file)):
        j = str.find(str(config_file[c]), s[0])
        if j != -1:
            i = str.find(str(config_file[c]), s[1])
            if i != -1:
                #a = config_file[c][:i] + str(s[1]) + " = " + modify(request.post_vars[s[1]]) + "\n"
                a = str(config_file[c])[:i]
                config_file[c] = a + s[1] + " = " + modify(request.post_vars[s[1]]) + "\n"
                return
            
def swap_module(m):
    import string
    try:
        if modules[m][0] == "off":
            at_modules = False
            for l in range(len(config_file)):
                if config_file[l] == "deployment_settings.modules = Storage(\n":
                    at_modules = True
                    continue
                if at_modules:
                    i = str.find(config_file[l], str(m + " = Storage("))
                    if i != -1:
                        config_file[l] = str("    " + config_file[l][5:])
                        l += 1
                        while config_file[l][4] == "#" and (config_file[l][5] == " " or config_file[l][5] == ")"):
                                config_file[l] = str("    " + config_file[l][5:])
                                l += 1
                        return
        else:
            at_modules = False
            for l in range(len(config_file)):
                if config_file[l] == "deployment_settings.modules = Storage(\n":
                    at_modules = True
                    continue
                if at_modules:
                    i = str.find(config_file[l], str(m + " = Storage("))
                    if i != -1:
                        config_file[l] = str("    #" + config_file[l][4:])
                        l += 1
                        while config_file[l][4] == " " or config_file[l][4] == ")":
                                config_file[l] = str("    #" + config_file[l][4:])
                                l += 1
                        return
    except:
        pass
            
def write_out(): 
    """Writes the 000_config file in sahana-eden once the setup form is submitted."""
    
    #NOTE: There may seem to be a large quantity of extranious punctuation, spacing, or other
    #      seemingly useless items being written to the file. This is because the 000_config
    #      file is a python script, as such it needs proper python punctuation to run.
    #out_list is a list that contains all the information that will be writen to 000_config
    #In order to prevent any potential concatenation errors all values are appended to the
    #   list as separate elements.
    
    #Iterates through settings and finds the corresponding submitted value then appends it
    #   to out_list.
    for s in settings:
        try:
            if request.post_vars[s[1]] != s[2]:
                edit_setting(s)
        except:
            pass
            
    
    #Iterates throught the modules dictionary
    for m in modules:
        #Checks for a keyerror, if found the module is automatically assumed to be on.
        try:
            #If a module is 'off' then the com variable will be set to #, this means that the
            #   code for that module will be commented out in 000_config, thus disabling it.
            if request.post_vars[m] != modules[m][0]:
                swap_module(m)
        except:
            print "A non-keyerror was found, however the program should still be functional."
    
    #This grabs the application name of eden, just in case it changes in the future.
    #If no name is provided the default is assumed to be eden.
    import io
    try:
        session.eden_name
    except NameError:
        session.eden_name = 'sahanaeden'
    if session.eden_name == None:
        session.eden_name = 'sahanaeden'
    
    #Opens the 000_config file within the eden program and writes out_list to it.
    import os
    try:
        file = open(os.path.join('applications', session.eden_name, 'models', '000_config.py'), 'w')
        try:
            file.writelines(config_file)
        except:
            print """Could not write to file. Ensure that you have
            permission to write to eden/models/000_config.py"""
        file.close()
    except IOError:
        print """Could not open file. Ensure that eden/models/000_config.py exists and
                 that you have permission to write to it."""
                
    #Redirects back to the original application
    redirect(URL(r=request, a=session.eden_name, c='default', f='index'))
    
def modify(s):
    """Returns proper python syntax based on variable type, type is assumed based on value
       within the s parameter. 123 is assumed to be an integer, True is assumed to be boolean,
       etc."""
    #If s is a T string for internalization, make it into a regular string
    s = str(s)
        
    if s == 'on':
        return 'True'
    elif s == 'off':
        return 'False'
    elif s == '':
        return '\"' + '\"'
    elif s.isdigit():
        return s
    elif s == 'None':
        return s
    else:
        return '\"' + s + '\"'